package com.nbx.app.zeuscmdport;


import java.nio.FloatBuffer;

import javax.microedition.khronos.egl.EGLConfig;
import javax.microedition.khronos.opengles.GL10;

import android.content.Context;
import android.graphics.Bitmap;
import android.opengl.GLU;
import android.opengl.GLUtils;
import android.view.MotionEvent;

/**
 * http://www.zeuscmd.com/tutorials/opengles/10-Transformations.php
 * 
 * @author 5109200610
 *
 */
public class Render18 extends RenderBase {

	private int mTextureID[] = new int[4];
	
	private int filter = 0;

	private float xrot = 0.0f;
	private float yrot = 0.0f;

	private float box[] = {
			// FRONT
			-0.5f, -0.5f,  0.5f,
			 0.5f, -0.5f,  0.5f,
			-0.5f,  0.5f,  0.5f,
			 0.5f,  0.5f,  0.5f,
			// BACK
			-0.5f, -0.5f, -0.5f,
			-0.5f,  0.5f, -0.5f,
			 0.5f, -0.5f, -0.5f,
			 0.5f,  0.5f, -0.5f,
			// LEFT
			-0.5f, -0.5f,  0.5f,
			-0.5f,  0.5f,  0.5f,
			-0.5f, -0.5f, -0.5f,
			-0.5f,  0.5f, -0.5f,
			// RIGHT
			 0.5f, -0.5f, -0.5f,
			 0.5f,  0.5f, -0.5f,
			 0.5f, -0.5f,  0.5f,
			 0.5f,  0.5f,  0.5f,
			// TOP
			-0.5f,  0.5f,  0.5f,
			 0.5f,  0.5f,  0.5f,
			 -0.5f,  0.5f, -0.5f,
			 0.5f,  0.5f, -0.5f,
			// BOTTOM
			-0.5f, -0.5f,  0.5f,
			-0.5f, -0.5f, -0.5f,
			 0.5f, -0.5f,  0.5f,
			 0.5f, -0.5f, -0.5f,
	};

	private float texCoords[] = {
			// FRONT
			 0.0f, 0.0f,
			 1.0f, 0.0f,
			 0.0f, 1.0f,
			 1.0f, 1.0f,
			// BACK
			 1.0f, 0.0f,
			 1.0f, 1.0f,
			 0.0f, 0.0f,
			 0.0f, 1.0f,
			// LEFT
			 2.0f, 0.0f,
			 2.0f, 2.0f,
			 0.0f, 0.0f,
			 0.0f, 2.0f,
			// RIGHT
			 2.0f, 0.0f,
			 2.0f, 2.0f,
			 0.0f, 0.0f,
			 0.0f, 2.0f,
			// TOP
			 0.0f, 0.0f,
			 1.0f, 0.0f,
			 0.0f, 1.0f,
			 1.0f, 1.0f,
			// BOTTOM
			 1.0f, 0.0f,
			 1.0f, 1.0f,
			 0.0f, 0.0f,
			 0.0f, 1.0f
	};

	private float lightAmbient[] = { 0.8f, 0.8f, 0.8f, 1.0f };

	private float matAmbient[] = { 0.8f, 0.8f, 0.8f, 1.0f };


	private FloatBuffer mBoxBuffer;
	private FloatBuffer mTexBuffer;
	
	private FloatBuffer mLightAmbientBuffer;
	
	private FloatBuffer mMatAmbientBuffer;
	
	public Render18(Context context) {
		super(context);
	}

	public void onSurfaceCreated(GL10 gl, EGLConfig config) {
		
		loadTextures(gl, R.drawable.nehe_zeus);
		mBoxBuffer = createFloatBuffer(box); 
		mTexBuffer = createFloatBuffer(texCoords); 
		mMatAmbientBuffer = createFloatBuffer(matAmbient); 
		mLightAmbientBuffer = createFloatBuffer(lightAmbient); 
		
		gl.glEnable(GL10.GL_TEXTURE_2D);

		gl.glEnable(GL10.GL_LIGHTING);
		gl.glEnable(GL10.GL_LIGHT0);

		gl.glMaterialfv(GL10.GL_FRONT_AND_BACK, GL10.GL_AMBIENT, mMatAmbientBuffer);
		
		gl.glLightfv(GL10.GL_LIGHT0, GL10.GL_AMBIENT, mLightAmbientBuffer);

		gl.glEnable(GL10.GL_DEPTH_TEST);
		gl.glDepthFunc(GL10.GL_LEQUAL);

		gl.glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
		gl.glClearDepthf(1.0f);

		gl.glVertexPointer(3, GL10.GL_FLOAT, 0, mBoxBuffer);
		gl.glTexCoordPointer(2, GL10.GL_FLOAT, 0, mTexBuffer);
		gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
		gl.glEnableClientState(GL10.GL_TEXTURE_COORD_ARRAY);

		gl.glEnable(GL10.GL_CULL_FACE);
		gl.glShadeModel(GL10.GL_SMOOTH);
	}

	public void onSurfaceChanged(GL10 gl, int width, int height) {
	
		gl.glMatrixMode(GL10.GL_PROJECTION);
		gl.glLoadIdentity();

		gl.glViewport(0, 0, width, height);
		GLU.gluPerspective(gl, 45.0f, 1.0f * width / height, 1.0f, 100.0f);

		gl.glMatrixMode(GL10.GL_MODELVIEW);
		gl.glLoadIdentity();
	}

	public void onDrawFrame(GL10 gl) {
		gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT);
		gl.glLoadIdentity();
		
		gl.glBindTexture(GL10.GL_TEXTURE_2D, mTextureID[filter]);

		GLU.gluLookAt(gl, 0.0f, 0.0f, 3.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f);

		gl.glRotatef(xrot, 1.0f, 0.0f, 0.0f);
		gl.glRotatef(yrot, 0.0f, 1.0f, 0.0f);

		// FRONT AND BACK
		gl.glColor4f(1.0f, 0.0f, 0.0f, 1.0f);
		gl.glNormal3f(0.0f, 0.0f, 1.0f);
		gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP, 0, 4);
		gl.glNormal3f(0.0f, 0.0f, -1.0f);
		gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP, 4, 4);

		// LEFT AND RIGHT
		gl.glColor4f(0.0f, 1.0f, 0.0f, 1.0f);
		gl.glNormal3f(-1.0f, 0.0f, 0.0f);
		gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP, 8, 4);
		gl.glNormal3f(1.0f, 0.0f, 0.0f);
		gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP, 12, 4);

		// TOP AND BOTTOM
		gl.glColor4f(0.0f, 0.0f, 1.0f, 1.0f);
		gl.glNormal3f(0.0f, 1.0f, 0.0f);
		gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP, 16, 4);
		gl.glNormal3f(0.0f, -1.0f, 0.0f);
		gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP, 20, 4);

		xrot += 2.0f;
		yrot += 3.0f;
	}
	
	private boolean loadTextures(GL10 gl, int res) {
		Bitmap bmp = getTextureFromBitmapResource(mContext, res);

		gl.glGenTextures(4, mTextureID, 0);

		// Texture 1
		gl.glBindTexture(GL10.GL_TEXTURE_2D, mTextureID[0]);
		gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MIN_FILTER,
				GL10.GL_NEAREST);
		gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MAG_FILTER,
				GL10.GL_NEAREST);
		GLUtils.texImage2D(GL10.GL_TEXTURE_2D, 0, bmp, 0);
		
		// Texture 2
		gl.glBindTexture(GL10.GL_TEXTURE_2D, mTextureID[1]);
		gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MIN_FILTER,
				GL10.GL_NEAREST);
		gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MAG_FILTER,
				GL10.GL_NEAREST);
		GLUtils.texImage2D(GL10.GL_TEXTURE_2D, 0, bmp, 0);

		// Texture 3
		gl.glBindTexture(GL10.GL_TEXTURE_2D, mTextureID[2]);
		gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MIN_FILTER,
				GL10.GL_NEAREST);
		gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MAG_FILTER,
				GL10.GL_NEAREST);
		GLUtils.texImage2D(GL10.GL_TEXTURE_2D, 0, bmp, 0);

		// Texture 4
		gl.glBindTexture(GL10.GL_TEXTURE_2D, mTextureID[3]);
		gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MIN_FILTER,
				GL10.GL_NEAREST);
		gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MAG_FILTER,
				GL10.GL_NEAREST);
		GLUtils.texImage2D(GL10.GL_TEXTURE_2D, 0, bmp, 0);
		
		gl.glBindTexture(GL10.GL_TEXTURE_2D, mTextureID[filter]);
		
		bmp.recycle();

		return true;
	}

	@Override
	public boolean handleTouchEvent(MotionEvent event) {
		filter ++;
		filter = filter % 4;
		return true;
	}
}